package com.yy.ttmodule.udp;


import android.support.annotation.NonNull;
import android.util.Log;

import com.yy.ttmodule.control.Constant;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentLinkedQueue;

public class UdpTxData {
    private static final String TAG = "UdpTxData";

    private static UdpTxData txData = null;
    private DatagramSocket socket;

    InetAddress address;
    int port = Constant.CLIENT_PORT;

    /**
     * 理论上这个缓存发送内容最大数值应该为1,应该只保留最后一次下发的数据包
     */
    private ConcurrentLinkedQueue<byte[]> packageQueue = new ConcurrentLinkedQueue<byte[]>();

    private UdpTxData() {
        try {
            address = InetAddress.getByName(Constant.CLIENT_IP);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    protected static UdpTxData getInstance() {
        if (txData == null) {
            synchronized (UdpTxData.class) {
                if (txData == null) {
                    txData = new UdpTxData();
                }
            }
        }
        return txData;
    }

    protected void setUdpPort(@NonNull DatagramSocket socket) {
        this.socket = socket;
    }

    private synchronized void sendPackage(byte[] bytes, int length) {
        try {
            address = InetAddress.getByName(Constant.CLIENT_IP);

            Log.d(TAG, "sendPackage >> " + ConvertData.byteArrayToHexString(bytes, length)
                    + "; packageQueue size : " + packageQueue.size());
            DatagramPacket packet = new DatagramPacket(bytes, length, address, port);
            socket.send(packet);
            //reMoveQueuePackage();
            delQueuePackage(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            //
            delQueuePackage(bytes);
        }
    }

    private synchronized void sendPackage(byte[] bytes) {
        sendPackage(bytes, bytes.length);
    }

    protected synchronized void sendPackage(byte[] parambytes, byte[] databytes) {
        byte[] srcBytes = new byte[UdpCommand.RECEIVE_PACK_LEN_MAX];
        byte[] resBytes = new byte[UdpCommand.RECEIVE_PACK_LEN_MAX];

        int len = 0;

        //包头
        for (int i = 0; i < UdpCommand.PACK_FRAME_HEADER.length; i++) {
            srcBytes[i] = UdpCommand.PACK_FRAME_HEADER[i];
        }
        len += UdpCommand.PACK_FRAME_HEADER.length;

        //类型
        byte[] paramdata = parambytes;//TxData.getInstance().getParam();//参数
        if (paramdata != null && paramdata.length > 0) {
            for (int i = 0; i < paramdata.length; i++) {
                srcBytes[len + i] = paramdata[i];
            }
            len += paramdata.length;
        }

        //byte[] data = TxData.getInstance().getData();
        //长度
        byte[] lendata = DataTypeConversion.shortToBytes((short)databytes.length);
        for (int i = 0; i < lendata.length; i++) {
            srcBytes[len + i] = lendata[i];
        }
        len += lendata.length;

        //数据
        if (databytes != null && databytes.length > 0) {
            for (int i = 0; i < databytes.length; i++) {
                srcBytes[len + i] = databytes[i];
            }
            len += databytes.length;
        }

        //加验证
        int resultLen = UdpDataUtil.comPackage(srcBytes, resBytes, len);

        byte[] sendData = new byte[resultLen];
        System.arraycopy(resBytes, 0, sendData, 0, resultLen);

        backUpPackage(sendData);
    }

    protected synchronized boolean isEmptyQueue() {
        return packageQueue.isEmpty();
    }

    private void backUpPackage(byte resBytes[]) {
        packageQueue.offer(resBytes);
    }

    protected synchronized void sendPackage() {
        if (!packageQueue.isEmpty()) {
            sendPackage(packageQueue.peek());
        }
    }

    protected synchronized void delQueuePackage(byte[] bytes) {
        Log.d(TAG, "delQueuePackage");
        if (!isEmptyQueue()) {
            packageQueue.remove(bytes);
        }
    }

    protected synchronized void reMoveQueuePackage() {
        Log.d(TAG, "reMoveQueuePackage");
        if (!isEmptyQueue()) {
            packageQueue.poll();
        }
    }

}
